<template>
  <div class="message-item" :class="[message.role, { error: message.error, cancelled: message.cancelled, [theme]: true }]">
    <div class="message-avatar">
      <div v-if="message.role === 'user'" class="user-avatar">👤</div>
      <div v-else class="ai-avatar">🤖</div>
    </div>
    <div class="message-content">
      <div v-if="message.loading" class="loading-indicator">
        <div class="loading-dots">
          <span></span>
          <span></span>
          <span></span>
        </div>
      </div>
      <div v-else-if="message.error" class="error-message">
        <div class="error-icon">❌</div>
        {{ message.content }}
      </div>
      <div v-else-if="message.cancelled" class="cancelled-message">
        <div class="cancelled-icon">⚠️</div>
        {{ message.content }}
      </div>
      <div v-else-if="shouldDisplayContent">
        <pre v-if="debugMode" class="debug-info">{{ debugInfo }}</pre>
        <div v-html="formattedContent" class="ai-response" ref="responseContent"></div>
      </div>
      <div v-else class="fallback-message">
        <div class="fallback-icon">⚠️</div>
        <div>
          <p>内容显示异常</p>
          <div class="fallback-content">{{ message.content || '无内容' }}</div>
          <div class="fallback-info">角色: {{ message.role || '未知' }}</div>
        </div>
      </div>
      <div class="message-meta">
        <div class="message-time">{{ formattedTime }}</div>
        <div class="message-actions" v-if="!message.loading && message.role === 'assistant'">
          <button class="action-btn" title="复制文本" @click="copyMessage">
            <span class="action-icon">📋</span>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, ref, watch, nextTick } from "vue";

// 开启调试模式 - 设置为true可以查看原始数据
const debugMode = ref(false);
// 响应内容的引用
const responseContent = ref(null);

// 使用Vue3的defineProps定义组件的props属性
// 这里定义了一个名为message的必传属性
// message必须是一个对象类型
// 用于接收父组件传递的消息数据，包含消息的内容、类型、状态等信息
const props = defineProps({
  message: {
    type: Object,    // 指定props的类型为Object
    required: true,  // 设置为必传属性
  },
  theme: {
    type: String,
    default: 'light'
  }
});

// 监听消息内容变化
watch(
  () => props.message.content,
  async () => {
    await nextTick();
    if (responseContent.value) {
      // 保证滚动到最新内容
      responseContent.value.scrollIntoView({ behavior: 'smooth', block: 'end' });
    }
  }
);

// 添加调试日志，帮助检查消息渲染问题
// watch(() => props.message, (newMsg) => {
//   console.log('MessageItem接收到消息更新:', {
//     id: newMsg.id,
//     role: newMsg.role,
//     contentLength: newMsg.content?.length || 0,
//     loading: newMsg.loading,
//     content: newMsg.content
//   });
// }, { deep: true, immediate: true });

// 调试信息
const debugInfo = computed(() => {
  return JSON.stringify(props.message, null, 2);
});

// 格式化消息内容
const formattedContent = computed(() => {
  console.log('格式化消息内容:', props.message.role, props.message.id);
  
  if (!props.message.content) return "【无内容】";
  
  let content = props.message.content;
  
  // 如果内容是JSON字符串，尝试解析
  try {
    if (typeof content === 'string' && content.trim().startsWith('{') && content.trim().endsWith('}')) {
      const jsonData = JSON.parse(content);
      content = jsonData.content || jsonData.text || jsonData.message || content;
    }
  } catch (e) {
    console.log('内容不是JSON格式');
  }
  
  // 检查是否为简单文本，如果是则包装成段落
  if (typeof content === 'string' && !content.includes('<') && !content.includes('>')) {
    // 处理简单换行
    content = content.split('\n').map(line => line.trim() ? `<p>${line}</p>` : '<br>').join('');
  } else {
    // 处理换行符
    content = content.replace(/\n/g, '<br>');
  }
  
  // 处理代码块 - 增强版
  content = content.replace(/```([\w]*)\n([\s\S]*?)```/g, (match, language, code) => {
    const languageClass = language ? ` language-${language}` : '';
    const languageLabel = language ? `<div class="code-language">${language}</div>` : '';
    return `<div class="code-block-wrapper">
      ${languageLabel}
      <pre class="code-block${languageClass}"><code>${code.trim()}</code></pre>
      <button class="copy-code-btn" onclick="navigator.clipboard.writeText(\`${code.trim().replace(/`/g, '\\`')}\`)">复制</button>
    </div>`;
  });
  
  // 处理行内代码
  content = content.replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>');
  
  // 处理列表
  content = content.replace(/^\s*[-*]\s+(.*?)$/gm, '<li>$1</li>');
  content = content.replace(/<li>.*?<\/li>/gs, '<ul>$&</ul>');
  
  // 处理标题
  content = content.replace(/^#{1,6}\s+(.*?)$/gm, (match, text) => {
    const level = match.trim().indexOf(' ');
    return `<h${level} class="content-heading">${text}</h${level}>`;
  });
  
  return content;
});

// 格式化时间
const formattedTime = computed(() => {
  if (!props.message.timestamp) return "";
  
  try {
    const date = new Date(props.message.timestamp);
    return date.toLocaleTimeString('zh-CN', {
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    });
  } catch (e) {
    return "";
  }
});

// 复制消息内容
const copyMessage = () => {
  const textToCopy = props.message.content;
  navigator.clipboard.writeText(textToCopy)
    .then(() => {
      alert('文本已复制到剪贴板');
    })
    .catch(err => {
      console.error('复制失败:', err);
    });
};

// 添加应急方案，确保消息总是能显示出来
const shouldDisplayContent = computed(() => {
  // 显示的条件：
  // 1. 不是加载中状态
  // 2. 没有被标记为错误或取消
  // 3. 有内容
  return !props.message.loading && 
         !props.message.error && 
         !props.message.cancelled &&
         props.message.content;
});
</script>

<style scoped>
.message-item {
  display: flex;
  margin-bottom: 24px;
  animation: fade-in 0.3s ease-in-out;
}

@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-avatar {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  margin-right: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}

.user-avatar {
  background-color: #e6f7ff;
  color: #1890ff;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 20px;
}

.ai-avatar {
  background-color: #f6ffed;
  color: #52c41a;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 20px;
}

.message-content {
  flex: 1;
  padding: 16px;
  border-radius: 12px;
  background-color: #f5f5f5;
  position: relative;
  overflow-wrap: break-word;
  word-wrap: break-word;
  word-break: break-word;
  max-width: 85%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.user .message-content {
  background-color: #e6f7ff;
  margin-left: auto;
}

.assistant .message-content {
  background-color: #f9f9f9;
  margin-right: auto;
}

.error .message-content {
  background-color: #fff2f0;
  border: 1px solid #ffccc7;
}

.cancelled .message-content {
  background-color: #f5f5f5;
  border: 1px dashed #d9d9d9;
  color: #999;
}

.message-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 10px;
}

.message-time {
  font-size: 12px;
  color: #999;
}

.message-actions {
  display: flex;
  gap: 8px;
}

.action-btn {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-size: 12px;
  color: #999;
  display: flex;
  align-items: center;
  transition: all 0.2s;
}

.action-btn:hover {
  color: #1890ff;
}

.action-icon {
  font-size: 14px;
}

.loading-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 24px;
}

.loading-dots {
  display: flex;
  align-items: center;
}

.loading-dots span {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin: 0 3px;
  background-color: #1890ff;
  border-radius: 50%;
  animation: dot-pulse 1.5s infinite ease-in-out;
}

.loading-dots span:nth-child(2) {
  animation-delay: 0.2s;
}

.loading-dots span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes dot-pulse {
  0%, 80%, 100% {
    transform: scale(0.8);
    opacity: 0.6;
  }
  40% {
    transform: scale(1.2);
    opacity: 1;
  }
}

.code-block-wrapper {
  position: relative;
  margin: 16px 0;
  border-radius: 8px;
  overflow: hidden;
}

.code-language {
  position: absolute;
  top: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0.6);
  color: #fff;
  padding: 2px 8px;
  font-size: 12px;
  border-bottom-left-radius: 8px;
}

.code-block {
  background-color: #1e1e1e;
  color: #d4d4d4;
  padding: 16px;
  border-radius: 8px;
  overflow-x: auto;
  font-family: 'Fira Code', Consolas, monospace;
  font-size: 14px;
  line-height: 1.5;
}

.copy-code-btn {
  position: absolute;
  right: 10px;
  bottom: 10px;
  background-color: rgba(255, 255, 255, 0.1);
  color: #d4d4d4;
  border: none;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 12px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.3s;
}

.code-block-wrapper:hover .copy-code-btn {
  opacity: 1;
}

.copy-code-btn:hover {
  background-color: rgba(255, 255, 255, 0.2);
}

.error-message, .cancelled-message {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.error-icon, .cancelled-icon {
  font-size: 18px;
  margin-right: 8px;
}

.error-message {
  color: #f5222d;
}

.cancelled-message {
  color: #999;
  font-style: italic;
}

.debug-info {
  background-color: #f8f8f8;
  border: 1px dashed #ccc;
  padding: 8px;
  font-family: monospace;
  white-space: pre-wrap;
  font-size: 12px;
  margin-bottom: 10px;
  overflow: auto;
  max-height: 200px;
}

.ai-response {
  line-height: 1.6;
  font-size: 15px;
  color: #333;
  white-space: pre-wrap;
  word-break: break-word;
}

.ai-response p {
  margin: 0.8em 0;
}

.content-heading {
  margin: 16px 0 8px;
  font-weight: 600;
  color: #222;
}

.highlight-update {
  background-color: rgba(82, 196, 26, 0.2);
}

.inline-code {
  background-color: #f0f0f0;
  padding: 2px 4px;
  border-radius: 3px;
  font-family: 'Fira Code', Consolas, monospace;
  font-size: 0.9em;
  color: #d63384;
}

/* 深色主题 */
.dark .message-content {
  background-color: #2d3748;
  color: #e2e8f0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.dark.user .message-content {
  background-color: #2c5282;
}

.dark.assistant .message-content {
  background-color: #2d3748;
}

.dark .ai-response {
  color: #e2e8f0;
}

.dark .inline-code {
  background-color: #383838;
  color: #f06595;
}

.dark .code-block {
  background-color: #1a1a1a;
  border: 1px solid #333;
}

.dark .content-heading {
  color: #90cdf4;
}

.dark .message-time {
  color: #a0aec0;
}

.dark .action-btn {
  color: #a0aec0;
}

.dark .action-btn:hover {
  color: #63b3ed;
}

/* 蓝色主题 */
.blue .message-content {
  background-color: #e6f7ff;
}

.blue.user .message-content {
  background-color: #bae7ff;
}

.blue.assistant .message-content {
  background-color: #f0f8ff;
}

.blue .ai-response {
  color: #0050b3;
}

.blue .content-heading {
  color: #0050b3;
}

.blue .inline-code {
  background-color: #e6f7ff;
  color: #1890ff;
}

.fallback-message {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  border-radius: 8px;
  background-color: #fff2f0;
  border: 1px solid #ffccc7;
}

.fallback-icon {
  font-size: 24px;
  margin-right: 12px;
}

.fallback-content {
  font-size: 15px;
  color: #333;
}

.fallback-info {
  font-size: 12px;
  color: #999;
}
</style>
